/*
 *  thermodamper.cpp
 *  EPPI-0.0
 *
 *  Created by Juan Carlos Garcia Orden on 23/09/2010
 *
 */

#include "thermostickslip.h"

ThermoStickSlip::ThermoStickSlip(ifstream &in, string cname, MecSystem *pSys)
:	Body(in,cname,pSys),
	pointNameA(),
	pointNameB(),
	theta(300.0)

{	
	dim = parentSystem->dim;	/** Must be set always.  dim belongs to the mother class Body */
	
	int i;
	char keyword[20];
	vector<string> auxsv(2);	/** Aux string vector */
	string auxs;
	vector<double> param(9);
	double mass = 0.0;
	map<string,string> param2;
	int thermal = 1;

	while (in >> keyword && strcmp(keyword,"ENDBODY") ) 
	{

		if(!strcmp(keyword,"MODE"))
		{
			in >> auxs;	
			if (!auxs.compare("log") || !auxs.compare("lin"))
			{
				param2["mode"] = auxs;
			}
			else 
			{
				cout << "Mode not recognized! Should be lin or log." << endl;
			}
			
		}


		/*if(!strcmp(keyword,"THERMAL"))
		{
			in >> auxs;	
			if (!auxs.compare("off"))
			{		
			thermal = 0;
			}
		}*/

		if(!strcmp(keyword,"P1"))
		{
			// keyword has the P1 label
			in >> pointNameA;	/** Reads the name of the point A */
			if(checkForSlash(pointNameA)==false)	addSystemName(pointNameA,parentSystem->name);
			in >> auxs;	// reads the P2 label
			in >> pointNameB;	/** Reads the name of the point B */
			if(checkForSlash(pointNameB)==false)	addSystemName(pointNameB,parentSystem->name);
			/** Extract the system name where the point is */
			auxsv[0] = pointNameA;
			auxsv[1] = pointNameB;
			in >> auxs;		// Reads C10 label
			in >> param[0];
			in >> auxs;		// Reads C11 label
			in >> param[1];
			in >> auxs;		// Reads BETAC label
			in >> param[2];
			in >> auxs;		// Reads C0 label
			in >> param[3];
			in >> auxs;		// Reads MU0 label
			in >> param[4];
			in >> auxs;		// Reads MU1 label
			in >> param[5];
			in >> auxs;		// Reads Q0 label
			in >> param[6];
			in >> auxs;		// Reads C label
			in >> param[7];
			in >> auxs;		// MASS label		
			in >> mass;
			
		}		
	}

	//vComponents.push_back(new TD(auxsv,param,param2,mass,dim));

	cout << thermal << endl;

	if(thermal)
	{
		vComponents.push_back(new TSS(auxsv,param,param2,mass,dim));
 	}
	else
	{
		//	cout << thermal << 1 << endl;
		// vComponents.push_back(new EP(auxsv,param,param2,mass,dim));
	}

	if(parentSystem->getProcNum()==parentSystem->getRankNum() ) cout << "	Body " << name << " succesfully read \n";
		
	vPointNamesSurface.push_back(pointNameA);
	vPointNamesSurface.push_back(pointNameB);
}

// ***

void ThermoStickSlip::setPTPointsComp()
{
	int j, k;
	vector<string> auxs;
	map<string, Point*, less<string> > maux;
	pair<string,Point*> mauxEntry;
	pair<string,int> sharedEntry;
	
	for(j=0; j<vComponents.size(); j++)		
	//Loop on the components
	{
		auxs = (vComponents[j]->getPointNames());
		for(k=0; k<auxs.size(); k++)		
		// Loop on the names of the points within each component
		{
			/** If the point it is not at the local process ... */
			if( (parentSystem->checkIfPointProcess(auxs[k]))==false )
			{
				/** ...  create it at root system, copying the original point from the remote process */
				parentSystem->createPointAtRoot( parentSystem->getPTPoint(auxs[k]) );
				/** ...  and add the name of the shared point at the remote process */
//				cout << "Nombre del sistema = " << parentSystem->name << endl;
//				cout << "en el proceso = " << parentSystem->getProcNum() << endl;
//				cout << "Nombre del punto = " << auxs[k] << endl;
				parentSystem->addRemoteSharedPoint(auxs[k],parentSystem->getProcNum());
			}
			mauxEntry.first = auxs[k];
			mauxEntry.second = (parentSystem->getPTPointLocal(auxs[k]));
			maux.insert(mauxEntry);
		}
		vComponents[j]->setMPoints(maux);
		maux.clear();
	}
}

// ***

void ThermoStickSlip::setPTPointsLoad()
{
	int j, k;
	vector<string> auxs;
	map<string, Point*, less<string> > maux;
	pair<string,Point*> mauxEntry;
	pair<string,int> sharedEntry;
	
	for(j=0; j<vLoads.size(); j++)		
	//Loop on the Loads
	{
		auxs = (vLoads[j]->getPointNames());
		for(k=0; k<auxs.size(); k++)		
		// Loop on the names of the points within each component
		{
			/** If the point it is not at the local process ... */
			if( (parentSystem->checkIfPointProcess(auxs[k]))==false )
			{
				/** ...  create it at root system, copying the original point from the remote process */
				parentSystem->createPointAtRoot( parentSystem->getPTPoint(auxs[k]) );
				/** ...  and add the name of the shared point at the remote process */
				parentSystem->addRemoteSharedPoint(auxs[k],parentSystem->getProcNum());
			}
			mauxEntry.first = auxs[k];
			mauxEntry.second = (parentSystem->getPTPointLocal(auxs[k]));
			maux.insert(mauxEntry);
		}
		vLoads[j]->setMPoints(maux);
		maux.clear();
	}
}

// ***
/*
void ThermoStickSlip::setPTPointsCons()
{
}
*/
// ***
/*
void ThermoStickSlip::setPTBodies()
{}
*/
// ***

void ThermoStickSlip::setPPointSurface()
{
	// Build the vector of pointers to the surface points
	vPPointSurface.resize(vPointNamesSurface.size());
	
	int i;
	string auxs;
	for(i=0;i<vPointNamesSurface.size();i++)
	{
		auxs = vPointNamesSurface[i];
		if(checkForSlash(auxs)==false)	addSystemName(auxs,parentSystem->name);
		vPPointSurface[i] = parentSystem->getPTPointLocal( auxs );
	}	
}

// ***

void ThermoStickSlip::setMatAtComp()
{}

// ***

void ThermoStickSlip::getBoundary(vector<vector<string> >& connect)
{}
	
// ***

void ThermoStickSlip::writeMSH(ofstream &fGraph)
{}

// ***

void ThermoStickSlip::writeVTU(ofstream &fGraph, bool& plotDispFlag, bool& plotProcFlag, bool& plotStressFlag)
{
	
	int i;
	int j;
	int nt;
	
	localFGraph << "<?xml version=\"1.0\"?>\n";
	localFGraph << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">\n";
	localFGraph << "	<UnstructuredGrid>\n";
	localFGraph << "		<Piece NumberOfPoints=\"" << vPointNamesSurface.size() << "\" NumberOfCells=\"" << 1 << "\">\n";
	localFGraph << "			<Points>\n";
	localFGraph << "				<DataArray type=\"Float64\" NumberOfComponents=\"3\" format=\"ascii\">";
	
	for(i=0; i<2; ++i)
	{
		localFGraph << "\n";
		localFGraph << "				";
		nt = vPPointSurface[i]->globalTNum.size();	// Number of translational dofs
		
		for (j=0; j<nt; ++j)
		{
			localFGraph << parentSystem->getDof( vPPointSurface[i]->globalTNum[j] ) << "\t"; 
		}
		if (nt<2 && nt!=0) localFGraph << 0.0;	// Second coordinate, just in case is 1D
		if (nt<3 && nt!=0) localFGraph << "\t" << 0.0;	// Third coordinate, just in case is 2D
	}
	
	
	localFGraph << "\n";
	localFGraph << "				</DataArray>\n";
	localFGraph << "			</Points>\n";
	localFGraph<< "			<Cells>\n";
	localFGraph << "				<DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">";
	
	localFGraph << "\n";
	localFGraph << "					";
	localFGraph << 1 << "\t";
	localFGraph << 0 << "\t";
	
	localFGraph << "\n";
	localFGraph << "				</DataArray>\n";
	localFGraph << "				<DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">";
	localFGraph << "\n";
	localFGraph << "					";
	
	localFGraph << 2 << "\t";
	
	localFGraph << "\n";
	localFGraph << "				</DataArray>\n";
	localFGraph << "				<DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">";
	localFGraph << "\n";
	localFGraph << "					";
	for (i=0; i<1; ++i)
	{
		localFGraph << 3 << "\t";
	}
	localFGraph << "\n";
	localFGraph << "				</DataArray>\n";
	localFGraph<< "			</Cells>\n";
	
	localFGraph << "		</Piece>\n";
	localFGraph << "	</UnstructuredGrid>\n";
	localFGraph << "</VTKFile>\n";

}

// ***

void ThermoStickSlip::writeOOGL(ofstream &fGraph)
{}

// ***

void ThermoStickSlip::writeFileTemp(const double& time, ofstream & outF)
{
	theta = vComponents[0]->getTemperature();
//	outF << time << " " << theta << endl;
	outF << " " << theta;
}

// ***

void ThermoStickSlip::setIniPosBody(vector<double>& iniValues)
{
	// Just one component, and one dof (temperature)
	theta = iniValues[0];
	(vComponents[0])->setIniDofs(iniValues);	
}
